import 'dart:io';

import 'package:dio/dio.dart';
import 'package:dio_cookie_manager/dio_cookie_manager.dart';
import 'package:cookie_jar/cookie_jar.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter_mvvm/service/rxNet/dbUtil.dart';
import 'package:flutter_mvvm/service/rxNet/stringUtil.dart';

import 'MD5Util.dart';

class NetUtils {
  /*
   * 获取get网络请求
   */
  static Future<Response<T>> getNet<T>(
      String path, Map<String, String> params) async {
    Dio dio = new Dio();
    dio.interceptors.add(CookieManager((await Cook.cookieJar)));
    print("地址：" + path);
    print("参数：" + fromMap2ParamsString(params));
    return await dio.get<T>(path + fromMap2ParamsString(params));
  }

  /*
   * 获取post网络请求
   */
  static Future<Response<T>> postNet<T>(
      String path, Map<String, String> params) async {
    Dio dio = new Dio();
    dio.interceptors.add(CookieManager((await Cook.cookieJar)));
    //获取cookies
    List<Cookie> cookiess = (await Cook.cookieJar).loadForRequest(
        Uri.parse("http://39.100.255.159:8080/" + 'api/auth/login'));
    //Save cookies
    (await Cook.cookieJar).saveFromResponse(
        Uri.parse("http://39.100.255.159:8080/" + 'api/auth/login'), cookiess);

    print('登录cookie====>,$cookiess');
    print("地址：" + path);
    print("参数：" + fromMap2ParamsString(params));
    print("参数：" + '$params');
    return await dio.post<T>(path, data: params);
  }

  /*
   * 获取get缓存请求
   */
  static Future<List<Map<String, dynamic>>> getCache(
      String path, Map<String, String> params) async {
    return DatabaseUtil.queryHttp(
        DatabaseUtil.database, getCacheKeyFromPath(path, params));
  }

  /*
   * 拼接请求参数
   */
  static String fromMap2ParamsString(Map<String, String> params) {
    if (params == null || params.length <= 0) {
      return "";
    }
    String paramsStr = "?";
    params.forEach((key, value) {
      paramsStr = paramsStr + key + "=" + value + "&";
    });
    return paramsStr;
  }

  /*
   * 生成Dio对象，确定是否需要缓存
   */
  static Dio createDio(String path, Map<String, String> params,
      Function(Object, bool) stringCallback, bool useCache) {
    Dio dio = new Dio();

    //需要缓存时，生成cacheKey
    if (useCache) {
      dio.interceptors.add(createInterceptor(
          getCacheKeyFromPath(path, params), dio, stringCallback));
    }
    return dio;
  }

  /*
   * 生成缓存拦截器
   */
  static InterceptorsWrapper createInterceptor(
      String cacheKey, Dio dio, Function(Object, bool) stringCallback) {
    InterceptorsWrapper interceptor =
        InterceptorsWrapper(onRequest: (RequestOptions options) async {
      DatabaseUtil.queryHttp(DatabaseUtil.database, cacheKey).then((cacheList) {
        if (cacheList.length > 0 &&
            !StringUtil.isEmpty(cacheList[0].toString())) {
          //返回数据库内容
          stringCallback(cacheList[0]["value"].toString(), true);
        }
      });
      return options;
    }, onResponse: (Response response) {
      return response;
    }, onError: (DioError e) {
      return e;
    });
    return interceptor;
  }

  static String getCacheKeyFromPath(String path, Map<String, String> params) {
    String cacheKey = "";
    if (!(StringUtil.isEmpty(path))) {
      cacheKey = cacheKey + MD5Util.generateMd5(path);
    } else {
      throw new Exception("请求地址不能为空！");
    }
    if (params != null && params.length > 0) {
      String paramsStr = "";
      params.forEach((key, value) {
        paramsStr = paramsStr + key + value;
      });
      cacheKey = cacheKey + MD5Util.generateMd5(paramsStr);
    }
    return cacheKey;
  }

  static void saveCache(String cacheKey, String value) {
    DatabaseUtil.queryHttp(DatabaseUtil.database, cacheKey).then((list) {
      if (list != null && list.length > 0) {
        //更新数据库数据
        DatabaseUtil.updateHttp(DatabaseUtil.database, cacheKey, value);
      } else {
        //插入数据库数据
        DatabaseUtil.insertHttp(DatabaseUtil.database, cacheKey, value);
      }
    });
  }
}

class Cook {
  //改为使用 PersistCookieJar，在文档中有介绍，PersistCookieJar将cookie保留在文件中，因此，如果应用程序退出，则cookie始终存在，除非显式调用delete
  static PersistCookieJar _cookieJar;

  static Future<PersistCookieJar> get cookieJar async {
    print('==================');
    print(_cookieJar);
    if (_cookieJar == null) {
      Directory appDocDir = await getApplicationDocumentsDirectory();
      String appDocPath = appDocDir.path;
      print('获取的文件系统目录 appDocPath： ' + appDocPath);
      _cookieJar = new PersistCookieJar(dir: appDocPath);
      print(_cookieJar);
    }
    return _cookieJar;
  }
}
